﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace GraphAlgorithms {
	public class AdjacencyList : GraphRepresentation {

		public AdjacencyList() {
			_adj = new Dictionary<Vertex, List<Vertex>>();
			V = new List<Vertex>();
			E = new List<Edge>();
			VDict = new Dictionary<string, Vertex>();
		}

		public AdjacencyList(string fileName) {
			_adj = new Dictionary<Vertex, List<Vertex>>();
			V = new List<Vertex>();
			E = new List<Edge>();
			VDict = new Dictionary<string, Vertex>();
			createGraph(fileName);
		}

		//the adjacency list representation uses a dictionary of lists 
		private Dictionary<Vertex, List<Vertex>> _adj;
		public Dictionary<Vertex, List<Vertex>> Adj {
			get { return _adj; }
			set { _adj = value; }
		}

		public void createGraph(string fileName) {
			//read in XML file and build an adjacency list
			if (!File.Exists(fileName)) return;
			StreamReader sRead = new StreamReader(fileName);
			string fileString = sRead.ReadToEnd();
			sRead.Close();
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(fileString);
			if (doc.ChildNodes[0].Name == "adjacency_list") {
				foreach (XmlNode node in doc.ChildNodes[0]) {
					V.Add(new Vertex(node.Attributes[0].Value)); //add vertex to vertex list
					_adj.Add(V[V.Count - 1], new List<Vertex>()); //add vertex to dictionary as key
					VDict.Add(node.Attributes[0].Value, V[V.Count - 1]);
				}
				for (int i = 0; i < V.Count; ++i) {
					XmlNode node = doc.ChildNodes[0].ChildNodes[i]; //for each vertex in the graph
					string s = node.Attributes[1].Value; //s is the adjacency list of the vertex
					string t = node.Attributes[2].Value; //t is the weight list 
					while (s != "") { //if the vertex has adjacent vertices 
						Vertex v = VDict[s.Substring(0, s.IndexOf(","))];
						_adj[V[i]].Add(v); //add the vertex to the adjacency list
						double w = double.Parse(t.Substring(0, t.IndexOf(",")));
						E.Add(new Edge(V[i], v, w)); //add an edge between vertices
						s = s.Remove(0, s.IndexOf(",") + 1); //parse out comma
						t = t.Remove(0, t.IndexOf(",") + 1); //parse out comma
					}
				}
			}
		}

	}
}
